package com.xyy.saas.payment.api.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.xyy.saas.payment.adpater.impl.WxCommonAdpter;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.api.BusinessPayApi;
import com.xyy.saas.payment.cores.bo.BusinessPayBo;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.cores.vo.BusinessPayVo;
import com.xyy.saas.payment.cores.vo.ResultVO;
import com.xyy.saas.payment.util.ApolloUtil;
import com.xyy.saas.payment.util.LeafUtil;
import com.xyy.saas.payment.util.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Author zhangwenxiong
 * @Date 2020/12/29 11:34
 * @Version 1.0
 */
@Service(version = "1.0.0")
@Slf4j
public class BusinessPayApiImpl implements BusinessPayApi {

    @Autowired
    private WxCommonAdpter wxCommonAdpter;

    @Autowired
    private LeafUtil leafUtil;

    @Override
    public ResultVO<BusinessPayBo> sendPack(BusinessPayVo businessPayVo, String sign) {
        BusinessPayBo businessPayBo = null;
        try {
            checkParam(businessPayVo);
        }catch (PaymentException e){
            log.warn("BusinessPayApiImpl#sendPack warn businessPayVo:{} paymentException:{}", JSON.toJSONString(businessPayVo), e.getErrCode());
            return ResultVO.createParamError();
        }

        try {
            String publicKey = ApolloUtil.getProperty(businessPayVo.getInvoker() + Constants.PUBLIC);
            if (!SignUtil.doCheck(businessPayVo, sign, publicKey)) {
                log.warn("BusinessPayApiImpl#sendPack warn businessPayVo:{} paymentException:{}", JSON.toJSONString(businessPayVo), ResultCodeEnum.SIGN_ERROR.getCode());
                return ResultVO.createSignError();
            }

            businessPayVo.setPayNo(leafUtil.getSnowflakeId());
            businessPayVo.setCallback("ykq_pack");
            businessPayBo = wxCommonAdpter.sendPackage(businessPayVo);
        }catch (PaymentException e){
            log.error("BusinessPayApiImpl#sendPack warn businessPayVo:{} paymentException:{}", JSON.toJSONString(businessPayVo), e.getErrCode());
            return e.getResult();
        }catch (Exception e){
            log.error("BusinessPayApiImpl#sendPack error businessPayVo:{}", JSON.toJSONString(businessPayVo), e);
            return ResultVO.create(ResultCodeEnum.DEFAULT_ERROR);
        }
        return ResultVO.createSuccess(businessPayBo);
    }

    @Override
    public ResultVO<BusinessPayBo> businessPay(BusinessPayVo businessPayVo, String sign) {
        BusinessPayBo businessPayBo = null;
        try {
            checkParam(businessPayVo);
        }catch (PaymentException e){
            log.warn("BusinessPayApiImpl#businessPay warn businessPayVo:{} paymentException:{}", JSON.toJSONString(businessPayVo), e.getErrCode());
            return ResultVO.createParamError();
        }

        try {
            String publicKey = ApolloUtil.getProperty(businessPayVo.getInvoker() + Constants.PUBLIC);
            if (!SignUtil.doCheck(businessPayVo, sign, publicKey)) {
                log.warn("BusinessPayApiImpl#businessPay warn businessPayVo:{} paymentException:{}", JSON.toJSONString(businessPayVo), ResultCodeEnum.SIGN_ERROR.getCode());
                return ResultVO.createSignError();
            }

            businessPayVo.setPayNo(leafUtil.getSnowflakeId());
            businessPayVo.setCallback("ykq_pay");
            businessPayBo = wxCommonAdpter.bussinessPay(businessPayVo);
        }catch (PaymentException e){
            log.error("BusinessPayApiImpl#businessPay warn businessPayVo:{} paymentException:{}", JSON.toJSONString(businessPayVo), e.getErrCode());
            return e.getResult();
        }catch (Exception e){
            log.error("BusinessPayApiImpl#businessPay error businessPayVo:{}", JSON.toJSONString(businessPayVo), e);
            return ResultVO.create(ResultCodeEnum.DEFAULT_ERROR);
        }
        return ResultVO.createSuccess(businessPayBo);
    }

    private void checkParam(BusinessPayVo businessPayVo) throws PaymentException {
        if (null == businessPayVo){
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }

        if (StringUtils.isEmpty(businessPayVo.getBusinessOrderType()) || StringUtils.isEmpty(businessPayVo.getPayMode()) ||
        null == businessPayVo.getBusinessPayType() || null == businessPayVo.getAmount() || StringUtils.isEmpty(businessPayVo.getOpenId())){
            throw new PaymentException(ResultCodeEnum.PARAM_ERROR);
        }
    }
}
